package com.aitaoxue.palx.base;

import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Map;

import org.apache.http.Header;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

import com.aitaoxue.palx.R;
import com.aitaoxue.palx.bean.ListEntity;
import com.aitaoxue.palx.cache.CacheManager;
import com.aitaoxue.palx.ui.empty.EmptyLayout;
import com.aitaoxue.palx.util.TDevice;
import com.loopj.android.http.AsyncHttpResponseHandler;

public abstract class BaseListFragment extends BaseTabFragment implements
		SwipeRefreshLayout.OnRefreshListener, OnItemClickListener,
		OnScrollListener {

	private static final String TAG = BaseListFragment.class.getSimpleName();

	public static final String BUNDLE_COURSE_TYPE = "BUNDLE_COURSE_TYPE";

	public String courseType;
	protected boolean LocalLog = false;
	protected String orderId = null;

	// @InjectView(R.id.swiperefreshlayout)
	protected SwipeRefreshLayout mSwipeRefreshLayout;
	//
	// @InjectView(R.id.listview)
	protected ListView mListView;

	protected ListBaseAdapter mAdapter;

	// @InjectView(R.id.error_layout)
	protected EmptyLayout mErrorLayout;

	@Override
	protected int getLayoutId() {
		return R.layout.fragment_pull_refresh_listview;
	}

	protected int mStoreEmptyState = -1;

	protected int mCurrentPage = 1;

	private AsyncTask<String, Void, ListEntity> mCacheTask;

	private ParserTask mParserTask;

	@Override
	public View onCreateView(LayoutInflater inflater,
			@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
		View view = inflater.inflate(getLayoutId(), container, false);
		// ButterKnife.inject(this, view);

		mSwipeRefreshLayout = (SwipeRefreshLayout) view
				.findViewById(R.id.swiperefreshlayout);
		mListView = (ListView) view.findViewById(R.id.listview);
		mErrorLayout = (EmptyLayout) view.findViewById(R.id.error_layout);

		initView(view);
		return view;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Bundle args = getArguments();
		if (args != null) {
			courseType = args.getString(BUNDLE_COURSE_TYPE);
			orderId = args.getString("orderid");
			if (orderId != null) {
				// 是从订单页面进来
				LocalLog = true;
			}
		}
	}

	@Override
	public void initView(View view) {
		mSwipeRefreshLayout.setOnRefreshListener(this);
		mSwipeRefreshLayout.setColorSchemeResources(
				R.color.swiperefresh_color1, R.color.swiperefresh_color2,
				R.color.swiperefresh_color3, R.color.swiperefresh_color4);

		// 点击错误页面
		mErrorLayout.setOnLayoutClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				mCurrentPage = 1;
				mState = STATE_REFRESH;
				mErrorLayout.setErrorType(EmptyLayout.NETWORK_LOADING);
				requestData(true, null);
			}
		});

		mListView.setOnItemClickListener(this);
		mListView.setOnScrollListener(this);

		if (mAdapter != null) {
			mListView.setAdapter(mAdapter);
			mErrorLayout.setErrorType(EmptyLayout.HIDE_LAYOUT);

			// if (courseType != null) {
			// switch (courseType) {
			// case Course.NOT_DEAL:
			// if (AppContext.getInstance().containsProperty("order6")
			// && AppContext.getInstance().getProperty("order6")
			// .equals("yes")) {
			// mErrorLayout.setErrorType(EmptyLayout.NETWORK_LOADING);
			// mCurrentPage = 1;
			// mState = STATE_REFRESH;
			// requestData(false, null);
			// AppContext.getInstance().setProperty("order6", "no");
			// }
			// break;
			// case Course.DEALING:
			// if (AppContext.getInstance().containsProperty("order1")
			// && AppContext.getInstance().getProperty("order1")
			// .equals("yes")) {
			// mErrorLayout.setErrorType(EmptyLayout.NETWORK_LOADING);
			// mCurrentPage = 1;
			// mState = STATE_REFRESH;
			// requestData(false, null);
			// AppContext.getInstance().setProperty("order1", "no");
			// }
			// break;
			// case Course.DEALED:
			// if (AppContext.getInstance().containsProperty("order2")
			// && AppContext.getInstance().getProperty("order2")
			// .equals("yes")) {
			// mErrorLayout.setErrorType(EmptyLayout.NETWORK_LOADING);
			// mCurrentPage = 1;
			// mState = STATE_REFRESH;
			// requestData(false, null);
			// AppContext.getInstance().setProperty("order2", "no");
			// }
			// break;
			// default:
			// break;
			// }
			// }
		} else {
			mAdapter = getListAdapter();
			mListView.setAdapter(mAdapter);

			if (requestDataIfViewCreated()) {
				mErrorLayout.setErrorType(EmptyLayout.NETWORK_LOADING);
				mCurrentPage = 1;
				mState = STATE_REFRESH;
				requestData(false, null);
				Log.d(TAG, "start request");
			} else {
				mErrorLayout.setErrorType(EmptyLayout.HIDE_LAYOUT);
			}
		}
		if (mStoreEmptyState != -1) {
			mErrorLayout.setErrorType(mStoreEmptyState);
		}
	}

	@Override
	public void onDestroyView() {
		mStoreEmptyState = mErrorLayout.getErrorState();
		super.onDestroyView();
	}

	@Override
	public void onDestroy() {
		cancelReadCacheTask();
		cancelParserTask();
		super.onDestroy();
	}

	protected abstract ListBaseAdapter getListAdapter();

	protected boolean requestDataIfViewCreated() {
		return true;
	}

	protected String getCacheKeyPrefix() {
		return null;
	}

	protected ListEntity parseList(byte[] response) throws Exception {
		return null;
	}

	protected ListEntity readList(Serializable seri) {
		return null;
	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
	}

	private String getCacheKey() {
		if (getCacheKeyPrefix() == null) {
			return null;
		}
		return new StringBuilder(getCacheKeyPrefix()).append("_")
				.append(mCurrentPage).append("_").append(TDevice.getPageSize())
				.toString();
	}

	protected void requestData(boolean refresh, Map<String, String> map) {
		String key = getCacheKey();
		if (TDevice.hasInternet()
				&& (key != null && (!CacheManager.isReadDataCache(
						getActivity(), key) || refresh))) {
			sendRequestData(map);
		} else {
			if (key == null) {
				sendRequestData(map);
			} else {
				readCacheData(key);
			}
		}
	}

	protected void sendRequestData(Map<String, String> map) {
	};

	private void readCacheData(String cacheKey) {
		cancelReadCacheTask();
		mCacheTask = new CacheTask(getActivity()).execute(cacheKey);
	}

	private void cancelReadCacheTask() {
		if (mCacheTask != null) {
			mCacheTask.cancel(true);
			mCacheTask = null;
		}
	}

	private class CacheTask extends AsyncTask<String, Void, ListEntity> {

		private WeakReference<Context> mContext;

		private CacheTask(Context context) {
			mContext = new WeakReference<Context>(context);
		}

		@Override
		protected ListEntity doInBackground(String... params) {
			Serializable seri = CacheManager.readObject(mContext.get(),
					params[0]);
			if (seri == null) {
				return null;
			} else {
				return readList(seri);
			}
		}

		@Override
		protected void onPostExecute(ListEntity list) {
			super.onPostExecute(list);
			if (list != null) {
				executeOnLoadDataSuccess(list.getList());
			} else {
				executeOnLoadDataError(null);
			}
			executeOnLoadFinish();
		}
	}

	private class SaveCacheTask extends AsyncTask<Void, Void, Void> {

		private WeakReference<Context> mContext;
		private Serializable seri;
		private String key;

		private SaveCacheTask(Context context, Serializable seri, String key) {
			mContext = new WeakReference<Context>(context);
			this.seri = seri;
			this.key = key;
		}

		@Override
		protected Void doInBackground(Void... arg0) {
			CacheManager.saveObject(mContext.get(), seri, key);
			return null;
		}
	}

	protected AsyncHttpResponseHandler mhandler = new AsyncHttpResponseHandler() {

		@Override
		public void onSuccess(int statusCode, Header[] headers,
				byte[] responseBytes) {
			if (isAdded()) {
				if (mState == STATE_REFRESH) {
					onRefreshNetworkSuccess();
				}
				executeParserTask(responseBytes);
			}
		}

		@Override
		public void onFailure(int arg0, Header[] arg1, byte[] arg2,
				Throwable arg3) {
			if (isAdded()) {
				readCacheData(getCacheKey());
			}
		}
	};

	protected void executeOnLoadDataSuccess(List<?> data) {
		if (mState == STATE_REFRESH)
			//mListView.setSelection(0);
			mAdapter.clear();
		if (data != null) {
			mAdapter.addData(data);
		}
		mErrorLayout.setErrorType(EmptyLayout.HIDE_LAYOUT);
		if (data == null || (data.size() == 0 && mState == STATE_REFRESH)) {
			mErrorLayout.setErrorType(EmptyLayout.NODATA);
		} else if (data.size() < TDevice.getPageSize()) {
			if (mState == STATE_REFRESH)
				mAdapter.setState(ListBaseAdapter.STATE_NO_MORE);
			else
				mAdapter.setState(ListBaseAdapter.STATE_NO_MORE);
		} else {
			mAdapter.setState(ListBaseAdapter.STATE_LOAD_MORE);
		}
	}

	protected void onRefreshNetworkSuccess() {

	}

	protected void executeOnLoadDataError(String error) {
		if (mCurrentPage == 1) {
			mErrorLayout.setErrorType(EmptyLayout.NETWORK_ERROR);
		} else {
			mErrorLayout.setErrorType(EmptyLayout.HIDE_LAYOUT);
			mAdapter.setState(ListBaseAdapter.STATE_NETWORK_ERROR);
			mAdapter.notifyDataSetChanged();
		}
	}

	protected void executeOnLoadFinish() {
		setSwipeRefreshLoadedState();
		mState = STATE_NONE;
	}

	private void executeParserTask(byte[] data) {
		cancelParserTask();
		mParserTask = new ParserTask(data);
		mParserTask.execute();
	}

	private void cancelParserTask() {
		if (mParserTask != null) {
			mParserTask.cancel(true);
			mParserTask = null;
		}
	}

	@Override
	public void onRefresh() {
		setSwipeRefreshLoadingState();
		mCurrentPage = 1;
		mState = STATE_REFRESH;
		requestData(true, null);
	}

	class ParserTask extends AsyncTask<Void, Void, String> {

		private byte[] reponseData;
		private boolean parserError;
		private List<?> list;

		public ParserTask(byte[] data) {
			this.reponseData = data;
		}

		@Override
		protected String doInBackground(Void... params) {
			try {
				ListEntity data = parseList(reponseData);
				if (getCacheKey() != null) {
					new SaveCacheTask(getActivity(), data, getCacheKey())
							.execute();
				}
				list = data.getList();
			} catch (Exception e) {
				e.printStackTrace();
				parserError = true;
			}
			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			if (parserError) {
				readCacheData(getCacheKey());
			} else {
				executeOnLoadDataSuccess(list);
				executeOnLoadFinish();
			}
		}
	}

	private void setSwipeRefreshLoadingState() {
		if (mSwipeRefreshLayout != null) {
			mSwipeRefreshLayout.setRefreshing(true);
			mSwipeRefreshLayout.setEnabled(false);
		}
	}

	private void setSwipeRefreshLoadedState() {
		if (mSwipeRefreshLayout != null) {
			mSwipeRefreshLayout.setRefreshing(false);
			mSwipeRefreshLayout.setEnabled(true);
		}
	}

	@Override
	public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {

	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		if (mAdapter == null || mAdapter.getCount() == 0) {
			return;
		}

		if (mState == STATE_LOADMORE || mState == STATE_REFRESH) {
			return;
		}

		boolean scrollEnd = false;
		try {
			if (view.getPositionForView(mAdapter.getFooterView()) == view
					.getLastVisiblePosition())
				scrollEnd = true;
		} catch (Exception e) {
			scrollEnd = false;
		}

		if (mState == STATE_NONE && scrollEnd) {
			if (mAdapter.getState() == ListBaseAdapter.STATE_LOAD_MORE) {
				mCurrentPage++;
				mState = STATE_LOADMORE;
				requestData(false, null);
			}
		}
	}
}
